package main

import (
	"github.com/google/uuid"
	"github.com/gorilla/websocket"
	"log"
	"net/http"
)

var manager = &Manager{
	//连接客户端
	Connections: make(map[*websocket.Conn]*ClientInfo),
	//当前主持人
	Current: nil,
	//当前词语
	CurrentKey: nil,
	//信息内容
	Message:      make(chan Message, 5),
	IsPlay:       false,
	CorrectCount: make(map[*websocket.Conn]bool),
	Queue:        make([]*websocket.Conn, 0),
	QueueIndex:   -1,
}

// 升级容器
var upgrade = websocket.Upgrader{ReadBufferSize: 512, WriteBufferSize: 512, CheckOrigin: func(r *http.Request) bool {
	return true
}}

// websocket
func gameWs(resp http.ResponseWriter, res *http.Request) {
	conn, err := upgrade.Upgrade(resp, res, nil)
	newUUID, _ := uuid.NewUUID()
	manager.Connections[conn] = &ClientInfo{
		ID:    newUUID.String(),
		Index: -1,
	}
	//连接失败
	if err != nil {
		log.Println("连接服务器失败！")
		resp.Header().Set("Content-Type", "application/json;charset=utf8")
		resp.Write(R{}.marshal(500, "无法连接到服务器", nil))
		return
	}
	log.Println("连接服务器成功！")

	//连接断开时操作
	defer afterHandle(conn)

	conn.WriteMessage(websocket.TextMessage, R{}.marshal(200, "操作成功", Message{Type: INFOS, Data: GetAllClientInfo()}))

	//循环
	for {
		m := Message{}
		err := conn.ReadJSON(&m)
		if err != nil {
			log.Println("读取数据失败！")
			break
		}
		m.Connect = conn
		manager.Message <- m
	}

}

// 最后处理问题
func afterHandle(conn *websocket.Conn) {
	conn.Close()
	info := manager.Connections[conn]
	log.Println(info.Name, " 退出了游戏")
	delete(manager.Connections, conn)
	//如果索引为-1则未加入游戏，未加入游戏则不进行删除队列以及玩家列表刷新
	if info.Index == -1 {
		return
	}

	//删除队列中的玩家
	if len(manager.Queue) == 1 {
		manager.Queue = make([]*websocket.Conn, 0)
	} else {
		manager.Queue = append(manager.Queue[:info.Index], manager.Queue[info.Index+1:]...)
	}

	//判断队列中是否还有玩家如果没有则游戏自动结束
	if len(manager.Queue) < 2 && manager.IsPlay {
		manager.ReGame()
		WriterMessageToAllClient(R{}.marshal(200, "游戏结束", Message{
			Type: GAMEOVER,
			Data: "游戏结束",
		}))
	}

	//返回当前列表中的玩家
	WriterMessageToAllClient(R{}.marshal(200, "玩家列表", Message{Type: INFOS, Data: GetAllClientInfo()}))
}
